﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace MountainORocks
{
    class Lightning
    {
        // Constants
        private const float timeToLive = 1f;
        private const float frameTime = 0.05f;
        private const float totalTime = 0.5f;
        private double currFrameTime = 0f;
        private double currTime = 0f;

        private const int divert_const = 50;

        // private variables
        private bool isAlive;
        private List<Vector2> edges;
        private int generations = 4;
        private Texture2D pixel; // used for drawing lines

        // Constructor
        public Lightning(Vector2 start, Vector2 end,GraphicsDevice graphics)
        {
            this.edges = new List<Vector2>();

            // add start and endics
            this.edges.Insert(0,start);
            this.edges.Insert(1,end);

            // creating an empty pixel
            this.pixel = new Texture2D(graphics, 1, 1);
            pixel.SetData(new[] { Color.White });
            
            // still alive 
            this.isAlive = true;
            this.currTime = totalTime;

            makeLigthning();
        }

        public void makeLigthning()
        {

            Random rand = new Random();

            List<Vector2> emptyEdges = new List<Vector2>();
            emptyEdges.Add(this.edges.First<Vector2>());
            emptyEdges.Add(this.edges.Last<Vector2>());

            this.edges = emptyEdges;
            if (((this.edges[1].X - this.edges[0].X) < 70) && ((this.edges[1].Y - this.edges[0].Y) < 10)) { generations = 2; }
            else { generations = 4; }
            for (int i = 0; i < generations; i++)
            {

                List<Vector2> newEdges = new List<Vector2>(this.edges);

                int counter = 0;

                for (int j = 0; j < this.edges.Count - 1; j++)
                {
                    // make it in the middle
                    Vector2 mid = new Vector2();
                    mid.X = (this.edges[j].X + this.edges.ElementAt<Vector2>(j + 1).X) / 2;
                    mid.Y = (this.edges.ElementAt<Vector2>(j).Y + this.edges.ElementAt<Vector2>(j + 1).Y) / 2;

                    // move it a little
                    mid.X += (rand.Next(divert_const) - (divert_const / 2));
                    mid.Y += (rand.Next(divert_const) - (divert_const / 2));

                    // add it
                    newEdges.Insert(j+(counter + 1), mid);
                    counter++;
                }

                counter = 0;

                this.edges = newEdges;
            }

            this.currFrameTime = frameTime;

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            if (isAlive)
            {
                for (int i = 0; i < this.edges.Count - 2; i++)
                {
                    if (i % 5 == 0) { DrawLineSegment(spriteBatch, this.edges[i], this.edges[i + 2], Color.White, 2); }

                    else { DrawLineSegment(spriteBatch, this.edges[i], this.edges[i + 1], Color.White, 2); }
                    
                }
            }
        }


        public void Update(GameTime gameTime)
        {
            if (isAlive)
            {
                currFrameTime -= gameTime.ElapsedGameTime.TotalSeconds;
                currTime -= gameTime.ElapsedGameTime.TotalSeconds;

                if (currFrameTime < 0) makeLigthning();
                if (currTime < 0) isAlive = false;
            }
        }

        private void DrawLineSegment(SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, int lineWidth)
        {
            float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
            float length = Vector2.Distance(point1, point2);
            spriteBatch.Draw(this.pixel, point1, null, Color.LightYellow,
            angle, Vector2.Zero, new Vector2(length, lineWidth),
            SpriteEffects.None, 0f);
        }
    }
}
